import * as vscode from 'vscode';
import { ProxyService } from "../../../src/services/proxyService";
import { LoginService } from '../../../src/services/loginService';
import { Logger } from '../../../src/logger/Logger';
import { getLocale, getPosition, setCopyText, updateText } from "@vscode-use/utils";
import * as fs from 'fs';

export class DocLinterWebviewRequestHandler {
    private proxyService: ProxyService;
    private isZh: boolean;

    constructor(private context: vscode.ExtensionContext, private webview: vscode.Webview, private _webview: vscode.Webview) {
        this.context = context;
        this.webview = webview;
        this._webview = _webview;
        this.proxyService = ProxyService.getInstance(this.context);
        this.isZh = getLocale().includes("zh");
    }


    /**
     * 处理获取记录
     */
    public async fetchRecord(data: any): Promise<void> {
        const { page, pageSize } = data;
        const url = `/api/aiService/report/getAll?pageNum=${page}&pageSize=${pageSize}`;
        const res = await this.proxyService.get(url);
        if (res.success) {
            this.webview.postMessage({
                type: "fetchRecordCallback",
                data: res.data,
            });
        } else {
            Logger.error(`获取记录失败: ${res.message}`);
        }
    }

    /**
     * 处理查看报告
     */
    public async viewReport(reportId: number): Promise<void> {
        const url = `/api/aiService/report/detail?reportId=${reportId}`;
        const res = await this.proxyService.get(url);
        if (res.success) {
            this.webview.postMessage({
                type: "viewReportCallback",
                data: res.data,
            });
        } else {
            Logger.error(`获取report失败: ${res.message}`);
        }
    }

    /**
     * 跳转到文件
     */
    public goToFile(filePath: string, line: number): void {
      if (!fs.existsSync(filePath)) {
        // 当前文件不存在
        this.webview.postMessage({
          type: "gotoFileCallback",
        });
        return;
       }
       let uri = vscode.Uri.file(filePath);
       vscode.commands.executeCommand("vscode.open", uri).then((res) => {
         let editor = vscode.window.activeTextEditor;
         if (editor) {
           const range = editor.document.lineAt(line - 1).range;
           editor.selection = new vscode.Selection(range.start, range.end);
           editor.revealRange(range);
         }
       }); 
    }

    /**
     * 取消报告
     */
    public async cancel(reportId: number) {
      const url = `/api/aiService/report/cancelReport?reportId=${reportId}`;
      const res = await this.proxyService.get(url);
      if (res.success) {
      this.webview.postMessage({
        type: "cancelCallback",
        data: res.data,
      });
      } else {
        Logger.error(`取消报告失败: ${res.message}`);
      }
    }

    /**
     * 比较
     */
    public compare(filePath: string, line: number, originText: string, fixText: string): void {
      if (!fs.existsSync(filePath)) {
        // 当前文件不存在
        this.webview.postMessage({
          type: "gotoFileCallback",
        });
        return;
      }
      const originData: string = fs.readFileSync(filePath, "utf-8");
      const lines: string[] = originData.split('\n');

      if (line > 0 && line <= lines.length) {
        const lineContent = lines[line - 1];
        // 确保要替换的内容在该行存在
        if (lineContent.includes(originText)) {
          lines[line - 1] = lineContent.replace(originText, fixText);
        }
      }

      const nextData = lines.join('\n');
      const list: string[] = filePath.split(".");
      const ext: string = list[list.length - 1];
      const DEFAULT_RULE_DIR = this.getVSCodeConfigDir();
      const nextPath: string = `${DEFAULT_RULE_DIR}/temp.${ext}`;
      fs.writeFileSync(nextPath, nextData);
      vscode.commands.executeCommand(
        "vscode.diff",
        vscode.Uri.file(nextPath),
        vscode.Uri.file(filePath),
        "advice->originText"
      );
    }

    /**
     * 复制
     */
    public copy(text: string): void {
      setCopyText(text || "");
      this.webview.postMessage({
        type: "copyCallback",
        data: "success",
      });
    }

    /**
     * 替换
     */
    public async replace(filePath: string, line: number, originText: string, fixText: string): Promise<void> {
      if (!fs.existsSync(filePath)) {
        // 当前文件不存在
        this.webview.postMessage({
          type: "gotoFileCallback",
        });
        return;
      }
      const curText = fs.readFileSync(filePath, "utf-8");
      const list = curText.split("\n");
      
      // 检查指定行是否存在
      if (line < 1 || line > list.length) {
        this.webview.postMessage({
          type: "gotoFileCallback",
        });
        return;
      }
      
      // 获取指定行的内容（行号从1开始，数组索引从0开始）
      const targetLine = list[line - 1];
      
      // 检查该行是否包含originText但不包含fixText
      if (!targetLine.includes(originText)) {
        // 指定行不包含原始文本，不需要替换
        return;
      }
      
      if (targetLine.includes(fixText)) {
        // 指定行已经包含修复文本，可能已经替换过了，不需要重复替换
        return;
      }
      
      // 计算指定行在整个文件中的起始位置
      let index = 0;
      for (let i = 0; i < line - 1; i++) {
        index += list[i].length + 1;
      }
      
      // 在指定行中查找originText的位置
      const nextIndex = targetLine.indexOf(originText);
      if (nextIndex > -1) {
        const start = index + nextIndex;
        const end = start + originText.length;
        const pos1 = getPosition(start);
        const pos2 = getPosition(end);
        updateText((edit) => {
          edit.replace(
            new vscode.Range(
              new vscode.Position(pos1.line, pos1.column),
              new vscode.Position(pos2.line, pos2.column)
            ),
            fixText
          );
        });
        
        // 替换完成后自动保存文件
        try {
          const document = await vscode.workspace.openTextDocument(filePath);
          await document.save();
        } catch (error) {
          console.error('自动保存文件失败:', error);
        }
      }
    }

    /**
     * 反馈
     */
    public async raise(status: number, reportId: number, defectId: number, reason: string): Promise<void> {
        const url = `/api/aiService/feedback/set`;
        const res = await this.proxyService.post(url, {
          reportId,
          defectId,
          status,
          reason: reason || "",
        });
        if (res.success) {
          this.webview.postMessage({
            type: "raiseCallback",
            data: {status},
          });
        } else {
          Logger.error(`raise失败: ${res.message}`);
        }
    }

    /**
     * 打开外部链接
     */
    public openExternal(url: string): void {
      vscode.env.openExternal(vscode.Uri.parse(url));
    }

    private getVSCodeConfigDir(): string {
      const path: string =
      process.env?.LOCALAPPDATA ||
      process.env?.VSCODE_CWD ||
      process.env?.USERPROFILE ||
      process.env?.ProgramFiles ||
      "c:/";
      return path;
    }

    /**
     * 获取语言
     */
    public getlangunage(): void {
      const lang = getLocale();
      this.webview.postMessage({
        type: "langCallback",
        data: lang,
      });
    }

    /**
     * 登录
     */
    public login() {
        LoginService.getInstance(this.context).startLogin({
            onSuccess: (userInfo) => {
              console.log('登录成功:', userInfo);
              
              this._webview?.postMessage({
                type: "queryHasLoginCallback",
                data: {
                  name: userInfo?.cnName,
                }
              });
            },
            onFailure: (reason, message) => {
              console.error('登录失败:', reason, message);
              this._webview?.postMessage({
                type: "thirdPartyLoginFailed",
                data: {
                  reason: reason,
                  message: message
                }
              });
            }
          });
    }

    /**
     * 查询是否登录
     */
    public async queryHasLogin() {
      const isLoggedIn = await LoginService.getInstance(this.context).isLoggedIn();
      if (isLoggedIn) {
          // 获取用户信息
          const userInfo = await LoginService.getInstance(this.context).getUserInfo();
          this._webview?.postMessage({
              type: "queryHasLoginCallback",
              data: {
                  name: userInfo?.cnName
              }
          });
      }
    }

  
}   